home *** CD-ROM | disk | FTP | other *** search
- /*
- * Memory mit Scaleable Fonts und mehreren geoeffneten Bildschirmen
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #if defined(sco)
- #include <string.h>
- #include <time.h>
- #else
- #include <strings.h>
- #endif
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <sys/time.h>
-
- #define _DoubleString
- #define DoubleDepth
- #define FlashSpeed 20
-
- #define MWidth(size) (dwidth*size+nplayers*size+3*size)
- #define MHeight(size) (dheight*size+2*size)
- #define MFieldX(x) (((x)+1)*size+offx)
- #define MFieldY(y) (((y)+1)*size+offy)
- #define SCol(x) ((x)*size+(dwidth+2)*size+offx)
- #define STop() (size)
- #define SRow(y) (dheight*size+size-(y+1)*bsize)
-
- static unsigned long current_time;
- static unsigned long get_current_time() {
- unsigned long ret;
- struct timeval timeval;
- #if !defined(sco)
- extern int gettimeofday (struct timeval *, struct timezone *);
- #endif
-
- gettimeofday( &timeval, NULL );
- ret = timeval.tv_sec * 100 + timeval.tv_usec/10000;
- return( ret );
- }
-
- class Color {
- friend class Port;
-
- public:
-
- Color( class Port *, int color_id, char *color );
- ~Color();
-
- GC gc_n;
- unsigned long pixel;
- int color_id;
- class Port *p;
-
- private:
- static void brighten( XColor *chg, XColor *org, double percent );
- Color *next;
- };
-
-
- class Port {
- friend class Tile;
-
- public:
- Port( char *disp_name, char *color, class Board &board );
- ~Port();
-
- static void close_all() { while(first) delete first; }
-
- int empty_queue();
- static int wait_event();
-
- void add_foreign_color( Port *first, char *color_name );
- void add_color( int id, char *color );
- void sub_color( int id );
-
- void redraw( int x, int y );
- void redraw_score( int x );
- void redraw( int x1, int y1, int x2, int y2 );
- void draw_block( int p, int x, int y );
-
- void tile_redraw( int fid );
- static void flush_all();
-
- int remove();
- void selected( int x, int y );
- unsigned long deselect( );
-
- Display *display;
- Screen *screen;
- Window window;
-
- GC gc_tile;
- GC gc_color_n( int id );
-
- void resize( int w, int h );
- char *color_name;
- int my_id;
-
- static int nplayers;
-
- int points;
- int Points( int id );
-
- private:
- class Tile **tile;
- class Tile *blank;
- class Tile *empty;
-
- Port *next;
- Color *colors;
-
- static Port *first;
-
- int size;
- int bsize;
- int offx, offy;
- int width,height;
-
- static int dsize;
-
- int lock_count;
- int lock[2];
- unsigned long lock_time;
- unsigned long flash_time;
-
- class Board &board;
-
- static struct fd_set readfds;
- static int nfds;
-
- Atom WmProtocolsPropId, WmDeleteWindowPropId;
-
- public:
- static int color_id;
- static int dwidth, dheight;
- };
-
- ///////////////////////////////////////////////////////////////////////////////
-
- class Tile {
- friend Port;
-
- public:
- Tile( Port *p, XFontStruct *font_info, int id );
- ~Tile();
-
- enum shade {
- light,
- bg,
- fg,
- dark
- };
- private:
- Display *display;
- Pixmap pixmap;
-
- };
-
- Tile::Tile( Port *p, XFontStruct *font_info, int id )
- {
- XCharStruct *cs;
- char sign;
- int offx, offy;
-
- // check justification of sign
- if ((id>=0)&&(id<=9)) sign = id+48;
- if ((id>=10)&&(id<=35)) sign = id-10+65;
- if ((id>=36)&&(id<=61)) sign = id-36+97;
- if (id>61) sign = id-62+60;
- if (id>67) sign = id-67+33;
-
- cs = &font_info->per_char[sign-font_info->min_char_or_byte2];
- offx = (p->size-cs->width)/2+cs->lbearing;
- offy = (p->size-font_info->ascent-font_info->descent)/2
- +font_info->ascent;
-
- // create Pixmap
- display = p->display; // for automatic destruction
-
- pixmap = XCreatePixmap( display, RootWindowOfScreen(p->screen),
- p->size, p->size, DefaultDepthOfScreen(p->screen) );
-
- // Background
- XSetForeground( display, p->gc_tile, (id!=-1)?bg:fg );
- XFillRectangle( display, pixmap, p->gc_tile, 0, 0, p->size, p->size );
-
- // TopLeft highlight
- XSetForeground( display, p->gc_tile, (id>=-1)?dark:light);
- XDrawLine( display, pixmap, p->gc_tile, 0, 0, p->size-1, 0 );
- XDrawLine( display, pixmap, p->gc_tile, 0, 0, 0, p->size-1 );
- #ifdef DoubleDepth
- if (id==-2) {
- XDrawLine( display, pixmap, p->gc_tile, 1, 1, p->size-2, 1 );
- XDrawLine( display, pixmap, p->gc_tile, 1, 1, 1, p->size-2 );
- }
- #endif
- if (id>=0) {
- #ifdef DoubleString
- XDrawString( display, pixmap, p->gc_tile, offx+2, offy+2, &sign, 1 );
- #endif
- XDrawString( display, pixmap, p->gc_tile, offx+1, offy+1, &sign, 1 );
- }
-
- // BottomRight shade
- XSetForeground( display, p->gc_tile, (id>=-1)?light:dark);
- XDrawLine( display, pixmap, p->gc_tile, 0, p->size-1, p->size-1, p->size-1);
- XDrawLine( display, pixmap, p->gc_tile, p->size-1, 0, p->size-1, p->size-1);
- #ifdef DoubleDepth
- if (id==-2) {
- XDrawLine( display, pixmap, p->gc_tile, 1, p->size-2, p->size-2, p->size-2);
- XDrawLine( display, pixmap, p->gc_tile, p->size-2, 1, p->size-2, p->size-2);
- }
- #endif
- if (id>=0) {
- #ifdef DoubleString
- XDrawString( display, pixmap, p->gc_tile, offx-2, offy-2, &sign, 1 );
- #endif
- XDrawString( display, pixmap, p->gc_tile, offx-1, offy-1, &sign, 1 );
- }
-
- // Foreground
- XSetForeground( display, p->gc_tile, fg );
- if (id>=0)
- XDrawString( display, pixmap, p->gc_tile, offx, offy, &sign, 1 );
- }
-
- Tile::~Tile() {
- XFreePixmap( display, pixmap );
- }
-
- ///////////////////////////////////////////////////////////////////////////////
-
- class Field {
- public:
- void reset( int id )
- { tile_id = id; lock_col = 0; locked=0; found=0; flash=0; gone=0; }
-
- int tile_id; // tile-index, used twice per board of course
- unsigned lock_col : 4; // color_id
- unsigned locked : 1; // geoeffnet
- unsigned found : 1; // Treffer
- unsigned flash : 1; // Highligh beim Blinken
- unsigned gone : 1; // auf Stapel gelegt
- };
-
- ///////////////////////////////////////////////////////////////////////////////
-
- class Board {
- public:
- Board( int width, int height );
- ~Board();
-
- void reset();
- void color_removed(int color_id);
- int tile_removed(int color_id);
- Field *field( int x, int y );
- Field *field( int fid );
-
- int ntiles;
- int tiles_left;
- unsigned long finished;
- int dx, dy; // dimension of board
- Field *f;
- };
-
-
- Board::Board( int width, int height )
- {
- dx = width;
- dy = height;
- ntiles = dx * dy;
- if (ntiles%2) dx++; // make even dimension
- ntiles = dx * dy;
- ntiles /= 2;
-
- f = new Field[2*ntiles];
- }
-
- Board::~Board() {
- delete f;
- }
-
- void Board::reset() {
- int i,j;
- Field help;
-
- for (i=0;i<2*ntiles;i++) f[i].reset(i/2);
- for (i=0;i<2*ntiles;i++) {
- j = rand()%(2*ntiles);
- help = f[i];
- f[i] = f[j];
- f[j] = help;
- }
- tiles_left=ntiles;
- finished=0;
- }
-
- void Board::color_removed( int id ) {
- int i;
- int back=0;
-
- for (i=0;i<2*ntiles;i++) {
- if (f[i].lock_col>=id) {
- if (f[i].lock_col==id) {
- f[i].locked=0;
- f[i].found =0;
- f[i].flash =0;
- if (f[i].gone) {
- f[i].gone=0;
- back++;
- }
- }
- f[i].lock_col--;
- }
- }
- tiles_left+=(back/2);
- }
-
- int Board::tile_removed(int /* color_id */) {
- if (--tiles_left) return 0;
- else {
- finished = current_time;
- return 1;
- }
- }
-
- Field *Board::field( int x, int y )
- {
- if ((x<0)||(x>=dx)||(y<0)||(y>=dy)) return(0);
- return( &f[x+y*dx] );
- }
-
- Field *Board::field( int fid )
- {
- return( field( fid%dx, fid/dx ) );
- }
-
- //////////////////////////////////////////////////////////////////////////////
-
- void Color::brighten( XColor *chg, XColor *org, double percent )
- {
- if (percent<0) {
- percent = 100+percent;
- chg->red = (unsigned short)(org->red*percent/100);
- chg->green = (unsigned short)(org->green*percent/100);
- chg->blue = (unsigned short)(org->blue*percent/100);
- }
- else {
- chg->red = (unsigned short)((65536-org->red)*percent/100 + org->red);
- chg->green = (unsigned short)((65536-org->green)*percent/100 + org->green);
- chg->blue = (unsigned short)((65536-org->blue)*percent/100 + org->blue);
- }
- }
-
- Color::Color( Port *p_in, int color_id, char *color_name ) :
- p(p_in)
- {
- unsigned long plane_mask = ~0x7;
- XColor def;
- XColor chg[8];
-
- this->color_id = color_id;
-
- if (!XAllocColorCells( p->display, DefaultColormapOfScreen(p->screen),
- True, // contiguous
- &plane_mask, // plane-mask
- 2, // number of planes
- &pixel, // field of pixels
- 1 // number of colors
- )) {
- fprintf( stderr, "out of colors\n" );
- exit(0);
- }
-
- int i;
- for (i=0;i<4;i++) {
- char colnam[40];
- sprintf(colnam,"%s%d",color_name,i+1);
- if (XLookupColor( p->display, DefaultColormapOfScreen(p->screen),
- colnam, &chg[i], &chg[i] ) ) break;
- }
- if (i<4) {
- XLookupColor( p->display, DefaultColormapOfScreen(p->screen), color_name,
- &def, &def );
- brighten(&chg[0],&def, 60.);
- brighten(&chg[1],&def, 20.);
- brighten(&chg[2],&def,-40.);
- brighten(&chg[3],&def,-60.);
- }
-
- for (i=0;i<4;i++) {
- chg[i].pixel = pixel+i;
- chg[i].flags = DoRed | DoGreen | DoBlue;
- }
-
- XStoreColors( p->display, DefaultColormapOfScreen(p->screen), chg, 4 );
-
- gc_n = XCreateGC( p->display, RootWindowOfScreen(p->screen), 0L, NULL );
- XSetPlaneMask( p->display, gc_n, ~0x3 );
- XSetForeground( p->display, gc_n, pixel );
-
- next=0;
- }
-
- Color::~Color() {
- XFreeGC( p->display, gc_n );
- if (next) delete next;
- }
-
- //////////////////////////////////////////////////////////////////////////////
-
- Port *Port::first = 0;
- int Port::color_id = 1;
- int Port::dwidth = 8;
- int Port::dheight = 9;
- int Port::dsize = 44;
- int Port::nplayers = 1;
-
- struct fd_set Port::readfds;
- int Port::nfds = 0;
-
-
- Port::Port( char *disp_name, char *color, Board &board_in ) :
- board(board_in)
- {
- char dsp_nam[30];
- static int w=0;
- int i;
-
- strcpy( dsp_nam, disp_name );
- if ((*disp_name)&&(!strchr(dsp_nam,':'))) {
- strcat( dsp_nam, ":0" );
- }
-
- // open connection to display and create a window
- display = XOpenDisplay( dsp_nam );
- if (!display) {
- fprintf( stderr, "can't open display '%s'.\n", dsp_nam );
- return;
- }
- screen = DefaultScreenOfDisplay( display );
- // XSynchronize(display,1);
-
- window = XCreateSimpleWindow( display, RootWindowOfScreen( screen ),
- 0, 0, MWidth(dsize), MHeight(dsize),
- 0, BlackPixelOfScreen(screen), WhitePixelOfScreen(screen) );
- XStoreName( display, window, color );
- XSelectInput( display, window, StructureNotifyMask|ExposureMask|ButtonPressMask );
-
- XSizeHints hints;
- hints.flags = USPosition | USSize | PAspect;
- hints.x = 100+(w%2)*(50+MWidth(dsize));
- hints.y = 100+(w/2)*(50+MHeight(dsize));
- hints.width = MWidth(dsize);
- hints.height = MHeight(dsize);
- hints.min_aspect.x = hints.max_aspect.x = MWidth(dsize);
- hints.min_aspect.y = hints.max_aspect.y = MHeight(dsize);
- XSetNormalHints( display,window,&hints );
- w++;
-
- this->width = hints.width;
- this->height = hints.height;
-
- Atom atom = XInternAtom(display,"PmWindowType",True);
- if (atom) {
- char* win_type = "FGnormal";
- XTextProperty prop;
- XStringListToTextProperty (&win_type, 1, &prop);
- XSetTextProperty (display, window, &prop, atom);
- XFree((void*)prop.value);
- }
-
- //
- // Reaktion auf Destroy Message anmelden
- //
- WmProtocolsPropId = XInternAtom(display,"WM_PROTOCOLS",False);
- WmDeleteWindowPropId = XInternAtom(display,"WM_DELETE_WINDOW",False);
- XSetWMProtocols( display, window, &WmDeleteWindowPropId, 1 );
-
- //
- // Fileselector merken
- //
- if (!nfds) FD_ZERO( &readfds );
- FD_SET( ConnectionNumber(display), &readfds );
- if (nfds<=ConnectionNumber(display)) nfds = ConnectionNumber(display)+1;
-
- tile = new Tile*[board.ntiles];
- for (i=0;i<board.ntiles;i++) tile[i]=0;
- blank = 0;
- empty = 0;
- // initialize graphic context for drawing tiles
- gc_tile = XCreateGC( display, RootWindowOfScreen(screen), 0L, NULL );
- XSetPlaneMask( display, gc_tile, 0x3 );
-
- // initialise tiles
- size=0;
- resize( dsize*dwidth, dsize*dheight );
-
- // exchange colors of ports
- colors=0;
- color_name = new char[strlen(color)+1];
- strcpy( color_name, color );
- my_id = color_id;
- add_color( 0, "yellow" );
- if (first) add_foreign_color( first, color_name );
- add_color( color_id, color_name );
-
- XSetWindowBackground( display, window, colors->pixel + 0x1 );
- XMapRaised( display, window );
-
- // connect to list of created displays
- next = first;
- first = this;
-
- color_id++;
- lock_count = 0;
- lock_time = 0;
- flash_time = 0;
- lock[0] = lock[1] = -1;
-
- points = 0;
- }
-
- void Port::add_foreign_color( Port *current, char *color_name ) {
- current->add_color( color_id, color_name );
- if (current->next) add_foreign_color(current->next,color_name);
- add_color( current->my_id, current->color_name );
- }
-
-
- void Port::sub_color( int id ) {
- Color *current= colors;
- Color *mark;
-
- //
- // Id dekrementieren
- //
- while(current) {
- if (current->color_id==id) mark = current;
- if (current->color_id>id) current->color_id--;
- current=current->next;
- }
- //
- // Farbe ausketten
- //
- if (mark==colors) {
- colors = mark->next;
- }
- else {
- current = colors;
- while( current->next != mark ) current = current->next;
- current->next = mark->next;
- }
- //
- // Farbe loeschen
- //
- mark->next = 0;
- delete mark;
-
- //
- // neue Fensterdimension:
- //
- offx = (width-MWidth(size))/2;
- XClearWindow(display,window);
- redraw(1,1,dwidth+nplayers+2,dheight+1);
- }
-
- Port::~Port() {
-
- nplayers--; // Zahl der Spieler
- board.color_removed(my_id); // Farbe im Brett freigeben
- color_id--; // Gesamtfarbenzaehler
- //
- // Farbe aus allen Ports austragen
- //
- Port *current;
-
- current=first;
- do {
- if (current->my_id>my_id) current->my_id--;
- current = current->next;
- } while(current);
-
- //
- // Port ausketten
- //
- if (this==first) {
- first = this->next;
- }
- else {
- current = first;
- while( current->next != this ) current = current->next;
- current->next = this->next;
- }
-
- //
- // Farbe aus den Ports austragen
- //
- for (current=first;current;current=current->next)
- current->sub_color( my_id );
-
- for (int i=0;i<board.ntiles;i++) {
- if (tile[i]) delete tile[i];
- }
- delete tile;
- if (blank) delete blank;
- if (empty) delete empty;
- delete colors;
- delete color_name;
- XFreeGC( display, gc_tile );
- XSync( display, 0 );
- XCloseDisplay( display );
- }
-
- void Port::add_color( int color_id, char *color_name )
- {
- Color *new_color;
-
- new_color = new Color( this, color_id, color_name );
- #if(1)
- new_color->next = colors;
- colors = new_color;
- #else
- new_color->next = 0;
- if (!colors) colors = new_color;
- else {
- Color *col = colors;
- while( col->next ) col=col->next;
- col->next=new_color;
- }
- #endif
- }
-
- int Port::empty_queue() {
- XEvent event;
-
- // XSync( display, 0 );
- while ( XEventsQueued( display, QueuedAfterFlush ) ) {
- XNextEvent( display, &event );
- switch( event.type ) {
- case ButtonPress:
- {
- switch(event.xbutton.button) {
- case 2:
- if (my_id==1) return 1;
-
- default:
- { if (board.finished&¤t_time>board.finished+5000) return 1;
- int x = (event.xbutton.x-offx-size)/size;
- int y = (event.xbutton.y-offy-size)/size;
- selected(x,y);
- }
- }
- break;
- }
- case Expose:
- {
- int x1=(event.xexpose.x-offx)/size;
- int y1=(event.xexpose.y-offy)/size;
- int x2=(event.xexpose.x+event.xexpose.width-offx)/size;
- int y2=(event.xexpose.y+event.xexpose.height-offy)/size;
- redraw( x1, y1, x2, y2 );
- break;
- }
- case ConfigureNotify:
- resize( event.xconfigure.width, event.xconfigure.height );
- break;
-
- case ClientMessage:
- if (event.xclient.message_type == WmProtocolsPropId) {
- Atom data_atom = (Atom)event.xclient.data.l[0];
- if (data_atom == WmDeleteWindowPropId) {
- return -1; // delete me !
- }
- }
- }
- }
- return 0;
- }
-
- int Port::wait_event() {
- static unsigned long next=0;
- int erg = 0;
-
- current_time = get_current_time();
- if (!next) next=current_time+100;
-
- if (current_time<next) {
- struct timeval timeout;
- unsigned long dist = next-current_time;
- struct fd_set readfds_cp;
-
- memcpy( &readfds_cp, &readfds, sizeof(readfds) );
- timeout.tv_sec = dist / 100;
- timeout.tv_usec = dist % 100;
- #if defined(sco)
- select( nfds, &readfds_cp, 0, 0, &timeout );
- #else
- select( nfds, (int*)&readfds_cp, 0, 0, &timeout );
- #endif
- current_time = get_current_time();
- }
-
- next = 0;
- for( Port *current = first; current; current=current->next ) {
- int delete_flag = current->empty_queue();
-
- if (delete_flag<0) {
- delete current;
- if (first) return erg+wait_event();
- else return 1;
- }
- else erg+=delete_flag;
- long current_next = current->deselect();
- if (current_next) {
- if (!next||current_next<next) next = current_next;
- }
- }
- return erg;
- }
-
- GC Port::gc_color_n( int id ) {
- Color *current=colors;
- int i;
-
- for (i=color_id-1;i>id;i--) current=current->next;
-
- return( current->gc_n );
- }
-
- int Port::Points( int id ) {
- Port *current=first;
- int i;
-
- for (i=color_id-1;i>id;i--) current=current->next;
- return( current->points );
- }
-
-
- void Port::redraw( int x, int y )
- {
- Field *f= board.field(x,y);
-
- if (!f) return;
-
- if (f->locked && !f->gone) {
- XFillRectangle( display, window,
- (f->flash)? gc_color_n(0) : gc_color_n(f->lock_col),
- MFieldX(x), MFieldY(y), size, size );
- XCopyArea( display, tile[f->tile_id]->pixmap, window, gc_tile,
- 0, 0, size, size, MFieldX(x), MFieldY(y) );
- }
- else {
- #if (1)
- XCopyArea( display, ((f->found)?empty->pixmap:blank->pixmap),
- window, gc_tile, 0, 0, size, size, MFieldX(x), MFieldY(y) );
- #else
- XCopyArea( display, tile[f->tile_id]->pixmap, window, gc_tile,
- 0, 0, size, size, MFieldX(x), MFieldY(y) );
- #endif
- XFillRectangle( display, window,
- (f->found)?gc_color_n(f->lock_col):gc_color_n(my_id),
- MFieldX(x), MFieldY(y), size, size );
- }
- }
-
- void Port::draw_block( int p, int x, int y ) {
- XFillRectangle( display, window, gc_color_n(p+1), x, y, size, bsize );
-
- XSetForeground( display, gc_tile, Tile::bg );
- XFillRectangle( display, window, gc_tile, x, y, size, bsize );
-
- XSetForeground( display, gc_tile, Tile::light );
- XDrawLine( display, window, gc_tile, x, y, x+size-1, y );
- XDrawLine( display, window, gc_tile, x, y, x, y+bsize-1 );
-
- XSetForeground( display, gc_tile, Tile::dark );
- XDrawLine( display, window, gc_tile, x, y+bsize-1, x+size-1, y+bsize-1 );
- XDrawLine( display, window, gc_tile, x+size-1, y, x+size-1, y+bsize-1 );
- }
-
- void Port::redraw_score( int x )
- {
- if (x>=nplayers) return;
-
- XFillRectangle( display, window, gc_color_n(my_id),
- SCol(x), STop(), size, dheight*size );
- XSetForeground( display, gc_tile, Tile::fg);
- XFillRectangle( display, window, gc_tile,
- SCol(x), STop(), size, dheight*size );
-
- XSetForeground( display, gc_tile, Tile::dark);
- XDrawLine( display, window, gc_tile,
- SCol(x), STop(), SCol(x+1)-1, STop() );
- XDrawLine( display, window, gc_tile,
- SCol(x), STop(), SCol(x), STop()+dheight*size-1 );
-
- XSetForeground( display, gc_tile, Tile::light);
- XDrawLine( display, window, gc_tile,
- SCol(x), STop()+dheight*size-1, SCol(x+1)-1, STop()+dheight*size-1 );
- XDrawLine( display, window, gc_tile,
- SCol(x+1)-1, STop(), SCol(x+1)-1, STop()+dheight*size-1 );
-
- int height = Points(x+1);
- for (int y=1;y<=height;y++) {
- draw_block( x, SCol(x), SRow(y-1) );
- }
- XFlush( display );
- }
-
- void Port::redraw( int x1, int y1, int x2, int y2 )
- {
- int x, y;
-
- if (x2>=dwidth+2) {
- for (x=(x1>=dwidth+2)?x1:dwidth+2;x<=x2;x++) {
- redraw_score(x-dwidth-2);
- }
- x2=dwidth+1;
- }
- if (x1>=dwidth+2) x1=dwidth+1;
-
- for (x=x1;x<=x2;x++) {
- for (y=y1;y<=y2;y++) {
- redraw( x-1, y-1 );
- }
- }
- }
-
- void Port::tile_redraw( int fid )
- {
- int x = fid%board.dx;
- int y = fid/board.dx;
-
-
- for ( Port *current = first; current; current = current->next )
- { current->redraw( x, y );
- XFlush( current->display );
- }
- }
-
- void Port::flush_all()
- {
- for ( Port *current = first; current; current = current->next )
- XFlush( current->display );
- }
-
- int Port::remove() {
- if ((lock_count>1)&&(board.field(lock[1])->found)) {
- board.field(lock[1])->gone = 1;
- tile_redraw( lock[1] );
- board.field(lock[0])->gone = 1;
- tile_redraw( lock[0] );
- lock_count=0;
- points+=2;
-
- for (Port *p=first;p;p=p->next) {
- p->redraw_score(my_id-1);
- }
- board.tile_removed(my_id);
- flash_time=0;
- return 1;
- }
- else {
- return 0;
- }
- }
-
- unsigned long Port::deselect()
- {
- unsigned long next = 0;
-
- if (flash_time&&flash_time<current_time) {
- board.field(lock[0])->flash ^= 1;
- board.field(lock[1])->flash ^= 1;
- tile_redraw(lock[0]);
- tile_redraw(lock[1]);
- next=flash_time=current_time+FlashSpeed;
- }
- if (lock_time&¤t_time<lock_time)
- return (!next||next>lock_time)?lock_time:next;
-
- if (lock_count>1) {
- if (!remove()) {
- board.field(lock[1])->locked = 0;
- tile_redraw( lock[1] );
- }
- }
- if (lock_count>0) {
- board.field(lock[0])->locked = 0;
- tile_redraw( lock[0] );
- }
- lock_count=0;
- lock_time =0;
-
- return 0;
- }
-
- void Port::selected( int x, int y )
- {
- int fid;
- Field *f= board.field(x,y);
-
- if (!f) return;
-
- //printf( "Pos: (%d,%d), Tile: %d, Locks %d\n", x,y,f->tile_id,lock_count );
- if (lock_count==2) {
- if (!remove()) {
- // XBell( display, 100 );
- return;
- }
- }
-
- fid = x+board.dx*y;
-
- //printf(" fid: %d, removed: %d, lock_id: %d\n", fid, f->removed, f->lock_id );
-
- if (f->found) return;
- if (f->locked) {
- #if (1)
- // XBell( display,100 );
- return;
- #else
- if (f->lock_col!=my_id){
- }
- else {
- if (lock[0]==fid) {
- lock[0]=lock[1];
- }
- lock_count--;
- f->locked=0;
- tile_redraw( fid );
- lock_time=current_time;
- return;
- }
- #endif
- }
-
- f->lock_col = my_id;
- f->locked = 1;
- lock[lock_count++] = fid;
-
- if (lock_count==2) {
- if (board.field(lock[0])->tile_id==board.field(lock[1])->tile_id) {
- board.field(lock[0])->found = 1;
- board.field(lock[0])->flash = 1;
- board.field(lock[1])->found = 1;
- board.field(lock[1])->flash = 1;
- tile_redraw( lock[0] );
- // tile_redraw( lock[1] );
- flash_time = current_time+FlashSpeed;
- }
- }
- tile_redraw( fid );
- lock_time = current_time + ((lock_count==2)?100:300);
- }
-
-
- #define ChFact 0.9
-
- void Port::resize( int width, int height )
- {
- int nsize;
- int i;
- char font_name[BUFSIZ];
-
- nsize = width/(dwidth+nplayers+3);
- if ( height/(dheight+2) < nsize ) nsize = height/(dheight+2);
- offx = (width-MWidth(nsize))/2;
- offy = (height-MHeight(nsize))/2;
-
- if (nsize==size) return;
- size=nsize;
- bsize = size/dwidth;
- this->width = width;
- this->height = height;
- // XResizeWindow( display, window, MWidth(size), MHeight(size) );
-
- // calculate screen resolution in dots per inch 25.4mm=1 inch
- int res_x = (int)(WidthOfScreen(screen)/(WidthMMOfScreen(screen)/25.4));
- int res_y = (int)(HeightOfScreen(screen)/(HeightMMOfScreen(screen)/25.4));
-
-
- sprintf( font_name, "-agfa-cg times-bold-r-normal-92504-%d-*-%d-%d-p-*-hp-roman8", (int)(size*ChFact), res_x, res_y );
- XFontStruct *font_info = XLoadQueryFont( display, font_name );
- if (!font_info) {
- for (i=(int)(size*ChFact);i>0;i--) {
- sprintf(font_name, "-adobe-courier-bold-r-normal-*-%d-*-%d-%d-*-*-*-*", i, res_x, res_y);
- font_info = XLoadQueryFont( display, font_name );
- if (font_info) break;
- }
- if (i==0) {
- fprintf( stderr, "unable to load font\n %s\n", font_name );
- fprintf( stderr, "is the font-server (/usr/bin/X11/fs) running ?\n" );
- exit(0);
- }
- }
- // printf( "%s", font_name );
- XSetFont( display, gc_tile, font_info->fid );
-
- #if (0)
- printf( "Size: %d\n", (int)(size*ChFact));
- printf( "Descent: %d\n", font_info->descent );
- printf( "Ascent: %d\n", font_info->ascent );
- printf( "Total: %d\n", font_info->ascent+font_info->descent );
- #endif
-
- for (i=0;i<board.ntiles;i++) {
- if ( tile[i] ) delete tile[i];
- tile[i] = new Tile( this, font_info, i );
- }
- if (blank) delete blank;
- if (empty) delete empty;
- empty = new Tile(this, font_info, -1);
- blank = new Tile(this, font_info, -2);
-
- XFreeFont( display, font_info );
- }
-
- //////////////////////////////////////////////////////////////////////////////
-
- void usage() {
- printf("usage: memory [small|normal|big] [display/color]*\n" );
- printf("e.g.: memory red hgr36:0.0/green hgr49:0.0/blue\n" );
- printf("The font-server has to be started at the selected hosts !!!\n" );
- exit(-1);
- }
-
- char *def_col[] = {
- "red", "DodgerBlue", "gold", "DeepPink", "tomato", "OliveDrab",
- "aquamarine", "brown", "bisque", "sienna" };
-
- main( int argc, char **argv )
- {
- int i;
- long timefield;
- char *color_name;
- Board *board;
-
- time(&timefield);
- srand((int)timefield);
-
- Port::nplayers = (argc-1);
-
- if (argc<2) usage();
- for (i=1;i<argc;i++) {
- if (!strcmp(argv[i],"small")) {
- Port::dwidth = 4; Port::dheight = 5;
- Port::nplayers--;
- }
- else if (!strcmp(argv[i],"normal")) {
- Port::dwidth = 8; Port::dheight = 9;
- Port::nplayers--;
- }
- else if (!strcmp(argv[i],"big")) {
- Port::dwidth = 11; Port::dheight = 12;
- Port::nplayers--;
- }
- else break;
- }
-
- if (!Port::nplayers) usage();
-
- board = new Board( Port::dwidth, Port::dheight );
-
- for (;i<argc;i++) {
- if ( color_name=strchr(argv[i],'/') ) {
- *color_name++ = '\0';
- new Port( argv[i], *color_name?color_name:def_col[Port::color_id-1], *board );
- }
- else {
- new Port( argv[i], def_col[Port::color_id-1], *board );
- }
- }
- board->reset();
-
- #if (1)
- while(!Port::wait_event());
- #else
- int n=10;
- while(--n) Port::wait_event();
- #endif
-
- Port::close_all();
- delete board;
-
- /* sleep(5); */
- }
-